<?php

namespace app\api\controller\user;

use addons\third\library\Application;
use addons\third\library\Service;
use app\common\controller\Api;
use app\common\library\Sms;
use app\common\library\Token;
use fast\Random;
use think\Hook;
use think\Validate;

class UserController extends Api
{
    protected $noNeedLogin = ['sms', 'register', 'forget', 'login', 'sign', 'third'];
    protected $noNeedRight = '*';

    public function sms()
    {
        $mobile = $this->request->post("mobile");
        $event  = $this->request->post("event");
        $event  = $event ?: 'register';

        if (!$mobile || !Validate::regex($mobile, "^1\d{10}$")) {
            $this->error(__('手机号不正确'));
        }
        $last = Sms::get($mobile, $event);
        if ($last && time() - $last['createtime'] < 60) {
            $this->error('发送频繁');
        }
        $ipSendTotal = \app\common\model\Sms::where(['ip' => $this->request->ip()])->whereTime('createtime', '-1 hours')->count();
        if ($ipSendTotal >= 5) {
            $this->error('发送频繁');
        }
        if ($event) {
            $userinfo = User::getByUsername($mobile);
            if ($event == 'register' && $userinfo) {
                $this->error('已被注册');
            }
            if (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
                $this->error('未注册');
            }
        }
        if (!Hook::get('sms_send')) {
            $this->error('请在后台插件管理安装短信验证插件');
        }
        $ret = Sms::send($mobile, null, $event);
        if ($ret) {
            $this->success('发送成功');
        } else {
            $this->error('发送失败');
        }
    }

    public function register()
    {
        $username = $this->request->post('username');
        $password = $this->request->post('password');
        $code     = $this->request->post('code');
        if (!$username || !$password) {
            $this->error('参数错误');
        }
        if (!Validate::regex($username, "^1\d{10}$")) {
            $this->error('手机号错误');
        }
        $ret = Sms::check($username, $code, 'register');
        if (!$ret) {
            $this->error('验证码错误');
        }
        $ret = $this->auth->register($username, $password, null, null, []);
        if ($ret) {
            $this->success('', [
                'userinfo' => $this->auth->getUserinfo(),
            ]);
        } else {
            $this->error($this->auth->getError());
        }
    }

    public function forget()
    {
        $username = $this->request->post('username');
        $code     = $this->request->post('code');
        $password = $this->request->post('password');
        if (!$password || !$username) {
            $this->error('参数错误');
        }
        if (!Validate::make()->check(['newpassword' => $password], ['newpassword' => 'require|regex:\S{6,30}'])) {
            $this->error('Password must be 6 to 30 characters');
        }
        if (!Validate::regex($username, '^1\d{10}$')) {
            $this->error('手机错误');
        }
        $user = User::getByUsername($username);
        if (!$user) {
            $this->error('用户错误');
        }
        if (!Sms::check($username, $code, 'resetpwd')) {
            $this->error('验证码错误');
        }
        Sms::flush($username, 'resetpwd');
        $this->auth->direct($user->id);
        if ($this->auth->changepwd($password, '', true)) {
            $this->success();
        } else {
            $this->error($this->auth->getError());
        }
    }

    public function logout()
    {
        $this->auth->logout();
        $this->success();
    }

    public function login()
    {
        $username = $this->request->post('username');
        $password = $this->request->post('password');
        if (!$username || !$password) {
            $this->error('参数错误');
        }
        $user = User::where('username', $username)->find();
        if ($user['status'] != 'normal') {
            $this->error('账号已注销');
        }
        $encryptPassword = $this->auth->getEncryptPassword($password, $user['salt']);
        if ($user['password'] != $encryptPassword) {
            $this->error('账号或者密码错误');
        }
        if ($this->auth->direct($user['id'])) {
            $this->success('', [
                'userinfo' => $this->auth->getUserinfo(),
            ]);
        } else {
            $this->error($this->auth->getError());
        }
    }

    public function sign()
    {
        $mobile  = $this->request->post('mobile');
        $captcha = $this->request->post('captcha');
        if (!$mobile || !$captcha) {
            $this->error(__('Invalid parameters'));
        }
        if (!Validate::regex($mobile, "^1\d{10}$")) {
            $this->error(__('Mobile is incorrect'));
        }
        if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
            $this->error(__('Captcha is incorrect'));
        }
        $user = User::getByUsername($mobile);
        if ($user) {
            if ($user->status != 'normal') {
                $this->error(__('Account is locked'));
            }
            $ret = $this->auth->direct($user->id);
        } else {
            $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
        }
        if ($ret) {
            Sms::flush($mobile, 'mobilelogin');
            $data = ['userinfo' => $this->auth->getUserinfo()];
            $this->success(__('Logged in successful'), $data);
        } else {
            $this->error($this->auth->getError());
        }
    }

    public function third()
    {
        $url      = url('user/index');
        $platform = $this->request->post("platform");
        $code     = $this->request->post("code");
        $config   = get_addon_config('third');
        if (!$config || !isset($config[$platform])) {
            $this->error(__('Invalid parameters'));
        }
        $app = new Application($config);
        //通过code换access_token和绑定会员
        $result = $app->{$platform}->getUserInfo(['code' => $code]);
        if ($result) {
            $loginret = Service::connect($platform, $result);
            if ($loginret) {
                $data = [
                    'userinfo'  => $this->auth->getUserinfo(),
                    'thirdinfo' => $result,
                ];
                $this->success(__('Logged in successful'), $data);
            }
        }
        $this->error(__('Operation failed'), $url);
    }

    public function profile()
    {
        $bio      = input('bio');
        $avatar   = input('avatar', '', 'trim,strip_tags,htmlspecialchars');
        $nickname = input('nickname');
        $user     = $this->auth->getUser();
        if ($bio) {
            $user['bio'] = $bio;
        }
        if ($nickname) {
            $user['nickname'] = $nickname;
        }
        if ($avatar) {
            $user['avatar'] = $avatar;
        }
        $user->save();
        $this->success();
    }

    public function off()
    {
        $user           = $this->auth->getUser();
        $user['status'] = 'hidden';
        $user->save();
        $this->success();
    }

    public function token()
    {
        $token     = $this->auth->getToken();
        $tokenInfo = Token::get($token);
        $this->success('', ['token' => $tokenInfo['token'], 'expires_in' => $tokenInfo['expires_in']]);
    }

    public function refresh()
    {
        $token = $this->auth->getToken();
        Token::delete($token);
        $token = Random::uuid();
        Token::set($token, $this->auth->getUser()['id'], 2592000);
        $tokenInfo = Token::get($token);
        $this->success('', [
            'token'      => $tokenInfo['token'],
            'expires_in' => $tokenInfo['expires_in'],
        ]);
    }

    public function info()
    {
        $user = User::find($this->auth->getUser()['id']);
        $this->success('', [
            'username' => $user['username'],
            'avatar'   => $user['avatar'],
            'bio'      => $user['bio'],
        ]);
    }
}